﻿using DDBS_Server.Controllers;
using DDBS_Server.Models;
using Raven.Abstractions.Data;
using Raven.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;

namespace DDBS_Server.APIControllers
{
    public partial class RavenDB
    {
        #region Database

        public string StoreSample(Sample sample)
        {
            using (IDocumentSession session = store.OpenSession())
            {
                try
                {
                    session.Store(sample);
                    session.SaveChanges();
                    return "--stored--";
                }
                catch (Exception e)
                {
                    return e.ToString();
                }
            }
        }

        public string StoreSample(Sample sample, FileStream data)
        {
            using (IDocumentSession session = store.OpenSession())
            {
                try
                {
                    session.Store(sample);
                    string id = sample.Id; // load asign Id
                    store.DatabaseCommands.PutAttachment(id, null, data, null);
                    session.SaveChanges();
                    return "--stored--";
                }
                catch (Exception e)
                {
                    return e.ToString();
                }
            }
        }

        public List<Sample> GetAllSamples()
        {
            using (IDocumentSession session = store.OpenSession())
            {
                List<Sample> results = new List<Sample>();
                try
                {
                    // Get all, should automagically retrieve from each shard.
                    results = session.Query<Sample>().ToList();
                    return results;
                }
                catch
                {
                    return results; // return empty list
                }
            }
        }

        // (Sample simSample, double tolerance)
        public List<Sample> GetSamplesByTopPeaks(Sample simSample, double tolerance, float ratioTolerance)
        {
            List<Peak> simTopPeaks = simSample.Peaks.OrderByDescending(p => p.V).Take(3).ToList();
            float simR1 = simTopPeaks[0].V / simTopPeaks[1].V;
            float simR2 = simTopPeaks[1].V / simTopPeaks[2].V;

            using (IDocumentSession session = store.OpenSession())
            {
                List<Sample> results = new List<Sample>();
                try
                {
                    results = session.Advanced // Advanced is used for direct NonLinq DocumentQuery methods (otherwise Query with LinqLike syntax is used).
                        .DocumentQuery<Sample, SamplesByTopPeaks>()
                        .WhereBetweenOrEqual("P1_Range", simTopPeaks[0].M - tolerance, simTopPeaks[0].M + tolerance)
                        .WhereBetweenOrEqual("P2_Range", simTopPeaks[1].M - tolerance, simTopPeaks[1].M + tolerance)
                        .WhereBetweenOrEqual("P3_Range", simTopPeaks[2].M - tolerance, simTopPeaks[2].M + tolerance)
                        .WhereBetweenOrEqual("R1_Range", (double)(simR1 - ratioTolerance), (double)(simR1 + ratioTolerance))
                        .WhereBetweenOrEqual("R2_Range", (double)(simR2 - ratioTolerance), (double)(simR2 + ratioTolerance))
                        .UsingDefaultOperator(QueryOperator.And) // DocumentQuery uses OR as default (.AndAlso() can be used instead).
                        .ToList();

                    foreach (Sample s in results)
                    {
                        s.Id = session.Advanced.GetDocumentId(s);
                    }

                    return results;
                }
                catch(Exception e)
                {
                    return results; // return empty list
                }
            }
        }

        public Sample GetSampleByID(string sid)
        {
            using (IDocumentSession session = store.OpenSession())
            {
                Sample result = new Sample();

                try
                {
                    result = session.Load<Sample>(sid);
                    //result = session.Query<Sample>("Employees/ByFirstName").Where(s => s.Id == sid).First();

                    return result;
                }
                catch (Exception e)
                {
                    return result; // return empty sample
                }
            }
        }

        public Attachment GetSampleAtch(string sid)
        {
            using (IDocumentSession session = store.OpenSession())
            {
                Attachment atch;

                try
                {
                    atch = store.DatabaseCommands.GetAttachment(sid);

                    return atch;
                }
                catch (Exception e)
                {
                    return null;
                }
            }
        }

        #endregion

        #region FileSystem



        #endregion
    }
}